package com.jianbo.proxy.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.smartboot.http.common.logging.Logger;
import org.smartboot.http.common.logging.LoggerFactory;

import com.jianbo.proxy.util.lhttp.HttpRequest;


/**
 * HttpUtil
 *
 * @author : lambo
 * @version : 1.0
 * @date :  2019-01-28 17:05
 **/
public class HttpUtil {
    private static Logger logger = LoggerFactory.getLogger(HttpUtil.class);

    public static class HttpResult {
        private int responseCode;
        private byte[] response;
        private Map<String, String> responseHeader;

        public int getResponseCode() {
            return responseCode;
        }
        public void setResponseCode(int responseCode) {
            this.responseCode = responseCode;
        }
        public byte[] getResponse() {
            return response;
        }
        public void setResponse(byte[] response) {
            this.response = response;
        }
        public Map<String, String> getResponseHeader() {
            return responseHeader;
        }
        public void setResponseHeader(Map<String, String> responseHeader) {
            this.responseHeader = responseHeader;
        }
    }

    public static HttpResult doRequest(String httpUrl, String method, byte[] data, Map<String, String> header) {

        HttpRequest request = new HttpRequest();
        request.setUrl(httpUrl);
        request.setRequestMethod(method);
        request.header(header);
        request.sendBytes(data);
        
        // Debug.info("before");
        Map<String, String> responseHeader = request.getResponseHaader();
        // Debug.info("responseHeader:", responseHeader);
        byte[] bytes = request.bytes();
        // Debug.info("length:" + bytes.length);
        int responseCode = request.code();
        // Debug.info("responseCode :" + responseCode);
        
        HttpResult httpResult = new HttpResult();
        httpResult.setResponse(bytes);
        httpResult.setResponseHeader(responseHeader);
        httpResult.setResponseCode(responseCode);
        request.disconnect();

        return httpResult;
    }

    public static HttpResult doRequest2(String httpUrl, String method, byte[] data, Map<String, String> header) {
        HttpURLConnection connection = null;
        InputStream is = null;
        try {
            // 创建远程url连接对象
            URL url = new URL(httpUrl);
            // 通过远程url连接对象打开一个连接，强转成httpURLConnection类
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接方式：get
            connection.setRequestMethod(method);
            // 设置连接主机服务器的超时时间：15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取远程返回的数据时间：60000毫秒
            connection.setReadTimeout(8000);
            if(header != null) {
                for(String key : header.keySet()) {
                    connection.setRequestProperty(key, header.get(key));
                }
            }
            connection.setDoOutput(true);
            connection.setDoInput(true);

            // 发送请求，GET 方法不允许传 data
            if(data != null && !"GET".equals(method)) {
                // 获取不到发送请求
                OutputStream os = connection.getOutputStream();
                os.write(data);
                os.flush();
                os.close();
            }

            connection.connect();

            Map<String, List<String>> fields = connection.getHeaderFields();
            Map<String, String> responseHeader = new LinkedHashMap<>();
            for(String field : fields.keySet()) {
                // if(field == null) {
                //     throw new RuntimeException("field is null" + JsonUtil.toJson(connection.getHeaderField(field)));
                // }
                if(field != null) {
                    responseHeader.put(field, connection.getHeaderField(field));
                }
            }

            int responseCode = connection.getResponseCode();

            // 通过connection连接，获取输入流
            is = connection.getInputStream();

            byte[] result;
            int length = connection.getHeaderFieldInt("Content-Length", -1);
            if(length != -1) {
                Debug.info("read by length:" + length);
                result = IoUtil.readToByteBufferByLength(is, length);
            } else {
                result = IoUtil.read(is);
            }
            // byte[] result = IoReadUtil.toByteArray(is, "utf-8");

            Debug.info("proxy response length:" + result.length);
            
            HttpResult httpResult = new HttpResult();
            httpResult.setResponse(result);
            httpResult.setResponseHeader(responseHeader);
            httpResult.setResponseCode(responseCode);

            return httpResult;

        } catch (IOException e) {
            logger.error(e.getMessage(), e);
            logger.error("doGet failed, url = {}", httpUrl);
        } finally {
            // 关闭资源
            IoUtil.closeIo(is);
            if (null != connection) {
                connection.disconnect();// 关闭远程连接
            }
        }
        return null;
    }
}
